package com.roocon.design_pattern.chapter03_readwrite_lock;

public class ShareData {

  private final char[] buffer;

  private final ReadWriteLock lock = new ReadWriteLock();

  public ShareData(int size) {
    this.buffer = new char[size];
    for (int i = 0; i < buffer.length; i++) {
      this.buffer[i] = '*';
    }
  }

  public char[] read() throws InterruptedException {
    try{
      lock.readLock();
      return this.doRead();
    }finally {
      lock.readUnlock();
    }
  }

  public void write(char c) throws InterruptedException {
    try {
      lock.writeLock();
      doWrite(c);
    } finally {
      lock.writeUnlock();
    }
  }

  private void doWrite(char c) {
    for (int i = 0; i < buffer.length; i++) {
      buffer[i] = c;
      slowly(10);
    }
  }

  private char[] doRead() {
    char[] buf = new char[buffer.length];
    for (int i = 0; i < buffer.length; i++) {
      buf[i] = buffer[i];
    }
    slowly(50);
    return buf;
  }

  private void slowly(int millis) {
    try {
      Thread.sleep(millis);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}
